package com.gitee.wsl.collections.iterator

import com.gitee.wsl.func.predicate.Predicate


/**
 * A generic implementation of an Iterator which iterates items based on an
 * inclusion test.
 *
 * @param <T> the type of iterated items
 *
 * @author cp  1997.09.05
</T> */
/**
 * Construct a [PredicateIterator] based on the specified Iterator
 * and the Predicate.
 *
 * @param m_iter  the Iterator of objects to filter
 * @param m_test  the inclusion test
 */
class PredicateIterator<T>(
    /**
     * Iterator to filter.
     */
    protected var m_iter: Iterator<T>,
    /**
     * Test to perform on each item.
     */
    protected var m_test: Predicate<T>,
) : Iterator<T> {
    // ----- Iterator interface ---------------------------------------------
    /**
     * {@inheritDoc}
     */
    override fun hasNext(): Boolean {
        // check if we've already check for the "next one"
        var fNext = m_fNext
        if (fNext) {
            return true
        }

        // find if there is a "next one"
        val iter = m_iter
        val test = m_test

        while (iter.hasNext()) {
            val next = iter.next()
            if (test(next)) {
                m_next = next
                fNext = true
                break
            }
        }

        // can't call remove now (because we'd end up potentially
        // removing the wrong one
        m_fPrev = false
        m_fNext = fNext

        return fNext
    }

    /**
     * {@inheritDoc}
     */
    override fun next(): T {
        if (hasNext()) {
            m_fNext = false
            m_fPrev = true
            return m_next as T
        } else {
            throw NoSuchElementException()
        }
    }

    /**
     * {@inheritDoc}
     */
//    fun remove() {
//        if (m_fPrev) {
//            m_fPrev = false
//            m_iter.remove()
//        } else {
//            throw IllegalStateException()
//        }
//    }


    // ----- data members ---------------------------------------------------

    /**
     * Is there a next item which passed the test?
     */
    protected var m_fNext: Boolean = false

    /**
     * Is there a previous item which passed the test and can be removed?
     */
    protected var m_fPrev: Boolean = false

    /**
     * The next item which passed the test.
     */
    protected var m_next: T? = null
}
